home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
jazlib.arc
/
JZINTHND.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-12-18
|
4KB
|
160 lines
Comment *
┌────────────────────────────────────────────────────────────────────────────┐
│jzinthnd.asm │
│This routine provides a generic interrupt interface for c. │
│This routine takes care of the task of saving the registers and │
│calling the user routine. Use jzinsint.c to install the interrupt handler │
│ │
│ (C) JazSoft Software by Jack A. Zucker (301) 794-5950 │
└────────────────────────────────────────────────────────────────────────────┘
*
;=============================================================================
; Definitions
;=============================================================================
TREG struc
wax dw ?
wbx dw ?
wcx dw ?
wdx dw ?
wsi dw ?
wdi dw ?
wds dw ?
wes dw ?
wflags dw ?
TREG ends
;=============================================================================
; Equates
;=============================================================================
STACKSIZE equ 1000h ; 4 kb stack size
;=============================================================================
; Data
;=============================================================================
DGROUP group _DATA
_DATA segment word public 'DATA'
assume ds:DGROUP
extrn STKHQQ:word ; upper stack limit (defined by MS/C)
public ISTACK,STKINCR
STKINCR dw 0 ; inc value for recursive interrupts
ISTACK db STACKSIZE dup ('STACK') ; Local stack for interrupts
WREG TREG <> ; structure for arg to int handler
_DATA ends
;=============================================================================
; Code
;=============================================================================
assume cs:_text
_text segment public byte 'code'
; the following 3 are declared public so MS/C can reach them:
public _jzinthnd,_gdseg,_gfunction
; the next set up public stuff is just for debugging:
public stacksize, stkincr, istack, _jzinthnd, savebp, savesp, saveds, savess
public _gdseg, gdseg, _gfunction, gfunction,wreg
_jzinthnd proc near
mov cs:savebp,bp ; save users registers
mov cs:savesp,sp ; in code segment variables
mov cs:savess,ss
mov cs:saveds,ds
push cs:gdseg ; recover c data segment
pop ds
; put register values in struc
pushf
pop WREG.wflags
mov WREG.wax,ax
mov WREG.wbx,bx
mov WREG.wcx,cx
mov WREG.wdx,dx
mov WREG.wsi,si
mov WREG.wdi,di
push cs:saveds
pop WREG.wds
mov WREG.wes,es
pushf
pop WREG.wflags
cli ; no interrupts here
mov ax,DGROUP ; get new interrupt stack
mov ss,ax ; over local stack space
mov sp,offset ISTACK
add STKINCR,STACKSIZE ; Stack grows downward so we
add sp,STKINCR ; start at the end of the buffer
sti ; interrupts back on
push STKHQQ ; save ms-c stack limit
mov ax,sp ; get top of stack
sub ax,STACKSIZE
add ax,4 ; get past "push STKHQQ" and
; add 2 for good measure.
mov STKHQQ,ax ; tell MS/C about it
Lea ax,wreg ; get address of register structure
push ax ; and put it on stack for c function
mov ax,WREG.wax ; restore orig ax
cld ; MS/C assumes this
mov bx,offset gfunction ; get address of c function
call [bx] ; call it indirectly !
add sp,2 ; get address of WREG off Stack
push ax ; save value. Later version will use it
sub STKINCR,STACKSIZE ; decrement for exit from recursion
pop ax ; restore return value (not used yet)
pop STKHQQ ; Give Ms/C back it's orig stack limit
mov bx,WREG.wbx ; restore users registers
mov cx,WREG.wcx ; from code segment
mov dx,WREG.wdx
mov bp,cs:savebp
mov si,WREG.wsi
mov di,WREG.wdi
mov ax,WREG.wes
mov es,ax
push WREG.wflags
popf
cli ; no interrupts here
mov ax,cs:savess ; restore original stack segment
mov ss,ax
mov sp,cs:savesp ; and offset
sti ; allow interrupts now
mov ax,cs:saveds ; restore interrupt data segment
mov ds,ax
mov ax,WREG.wax ; restore ax
iret ; return back to caller
savebp dw 0
savesp dw 0
saveds dw 0
savess dw 0
_gdseg label far
gdseg dw 0 ; hold global data segment
_gfunction label far
gfunction dw 0 ; place to hold function address
_jzinthnd endp
_text ends
end